﻿using System;
using System.Data;
using System.Web.UI.WebControls;
using VitCode.Castle.DataAccess;
using CRS.Core.Entities;
using CRS.Core.DataAccess;
using System.Collections.Generic;
using VitCode.Web.UI.WebControls;
using System.Collections.Specialized;
using System.Text.RegularExpressions;

namespace CRS.Web.BaseData
{
    public partial class InventoryEdit : System.Web.UI.Page
    {
        #region 盘点货品列表表头定义
        /// <summary>
        ///  条码
        /// </summary>
        private const string BARCODE = "条码";
        /// <summary>
        ///  货物名称
        /// </summary>
        private const string GOODSNAME = "货物名称";
        /// <summary>
        ///  库存数
        /// </summary>
        private const string STOCKAMOUNT = "库存数";
        /// <summary>
        /// 当前盘点数量
        /// </summary>
        private const string CURRINVENTORYMOUNT = "当前盘点数量";
        /// <summary>
        /// 盘亏数
        /// </summary>
        private const string SHORTAGEMOUNT = "盘亏数";
        /// <summary>
        ///  盘亏金额
        /// </summary>
        private const string SHORTAGEMONEY = "盘亏金额";
        /// <summary>
        ///  货品ID
        /// </summary>
        private const string GOODSID = "货品ID";
        /// <summary>
        ///  盘点货品条目ID
        /// </summary>
        private const string INVENTORYITEMID = "盘点货品条目ID";
        #endregion
        
        protected void Page_Load(object sender, EventArgs e)
        {
            Response.Write("<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>");
            
            pgList.DataSourceDelegate=new VitCode.Web.UI.PaginationGrid.GridDataSourceDelegate(BindData);
            if(!IsPostBack)
            {
                Session["_inventoryInfos"] = null;
                Session["InvenDataSource"] = null;
                Session["_woCode"] = null;  
                InitInfo();
                pgList.BindGrid();
            }
        }

        private string WoCode
        {
            get
            {
                if (Request.QueryString["billNo"] != null)
                    Session["_woCode"] = Request.QueryString["billNo"];
                if (Session["_woCode"] == null)
                    return string.Empty;
                return Session["_woCode"].ToString();
            }
            set { Session["_woCode"] = value; }
        }

        private InventoryInfo _inventoryInfos;
        private InventoryInfo InventoryInfos
        {
            get
            {
                if(_inventoryInfos==null)
                {
                    if(Session["_inventoryInfos"]!=null)
                        _inventoryInfos = (InventoryInfo) Session["_inventoryInfos"];
                    else if(!string.IsNullOrEmpty(WoCode))
                    {
                        var coreAccess = new CoreDataAccess();
                        _inventoryInfos =
                            coreAccess.GetSingleObjectByProVal("InventoryInfo", "WoCode", WoCode) as InventoryInfo;
                        Session["_inventoryInfos"] = _inventoryInfos;
                    }
                    else
                    {
                        _inventoryInfos=new InventoryInfo();
                        Session["_inventoryInfos"] = _inventoryInfos;
                    }
                }
                else
                {
                    Session["_inventoryInfos"] = _inventoryInfos;
                }
                return _inventoryInfos;
            }
            set { _inventoryInfos = value; }
        }

        private string InventoryState
        {
            get
            {
                if (string.IsNullOrEmpty(WoCode))
                    InventoryInfos.State = "新建";
                return InventoryInfos.State;
            }
            set { InventoryInfos.State = value; }
        }

        private void InitInfo()
        {
            if (!string.IsNullOrEmpty(WoCode))
            {
                lblBillNo.Text = InventoryInfos.WoCode;
                lblInventory.Text = InventoryInfos.CreateUser.Name;
                txtDate.Text = InventoryInfos.ReceivedDate.ToString("yyyy-MM-dd HH:mm:ss");
                lblCreateTime.Text = InventoryInfos.CreateDate.ToString("yyyy-MM-dd HH:mm:ss");
                txtMemo.Text = InventoryInfos.Memo;
                //获取盘点货品信息
                GetInventoryItemInfo();
                if (InventoryInfos.State == "盘点中")
                {
                    btnDelete.Enabled = false;
                    btnEndInventory.Enabled = true;
                    txtBarcode.Enabled = true;
                    txtAmount.Enabled = true;
                    btnAdd.Enabled = true;
                }
                if(InventoryInfos.State=="已完成")
                {
                    btnSave.Enabled = false;
                    btnDelete.Enabled = false;
                    btnInventory.Enabled = false;
                    btnEndInventory.Enabled = false;
                }
            }
            else
            {
                lblBillNo.Text = "VIC_" + DateTime.Now.Year.ToString() + DateTime.Now.Month.ToString() +
                                 DateTime.Now.Day.ToString() + DateTime.Now.Hour.ToString() +
                                 DateTime.Now.Minute.ToString()+DateTime.Now.Second.ToString();
                lblInventory.Text = Server.UrlDecode(GenericContext.CurrUserName);
                lblCreateTime.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            }
            SetInventoryAmountInfo();
        }

        private void GetInventoryItemInfo()
        {
            if(!string.IsNullOrEmpty(WoCode))
            {
                var access = new CoreDataAccess();
                var sql =
                    @"select gi.*,g.Code,g.Name,g.BasePrice from dbo.CRS_Core_GoodsInventoryItem gi
                        left join dbo.CRS_Core_InventoryInfo i on gi.InventoryInfoId=i.Id
                        left join dbo.CRS_Core_GoodsInfo g on gi.GoodsId=g.Id";
                var itemList = access.GetDataTableBySql(sql);
                foreach(DataRow dataRow in itemList.Rows)
                {
                    var row = DataSource.NewRow();
                    row[INVENTORYITEMID] = dataRow["Id"].ToString();
                    row[BARCODE] = dataRow["Code"].ToString();
                    row[GOODSNAME] = dataRow["Name"].ToString();
                    row[STOCKAMOUNT] = dataRow["OrgAmount"].ToString();
                    row[CURRINVENTORYMOUNT] = dataRow["CurrAmount"].ToString();
                    if (Convert.ToInt32(row[STOCKAMOUNT]) > Convert.ToInt32(row[CURRINVENTORYMOUNT]))
                        row[SHORTAGEMOUNT] = Convert.ToInt32(row[STOCKAMOUNT]) -
                                             Convert.ToInt32(row[CURRINVENTORYMOUNT]);
                    else
                        row[SHORTAGEMOUNT] = 0;
                    row[SHORTAGEMONEY] = string.Format("{0:C2}",Convert.ToInt32(row[SHORTAGEMOUNT]) * Convert.ToDouble(dataRow["BasePrice"]));
                    row[GOODSID] = dataRow["GoodsId"].ToString();
                    DataSource.Rows.Add(row);
                }
            }
        }

        protected void tabMenu_MenuItemClick(object sender, MenuEventArgs e)
        {
            if(tabMenu.SelectedValue=="0")
            {
                BillInfo.Visible = true;
                GoodsInfoDiv.Visible = false;
            }
            else
            {
                BillInfo.Visible = false;
                GoodsInfoDiv.Visible = true;
                txtBarcode.Focus();
            }
        }

        private DataTable _IdataSource;

        private DataTable DataSource
        {
            get
            {
                if (Session["InvenDataSource"] != null)
                    _IdataSource = (DataTable)Session["InvenDataSource"];
                else
                {
                    _IdataSource = InitData();
                    Session["InvenDataSource"] = _IdataSource;
                }
                return _IdataSource;
            }
        }

        private object BindData()
        {
            return DataSource;
        }

        private DataTable InitData()
        {
            var table = new DataTable();
            table.Columns.Add(INVENTORYITEMID);
            table.Columns.Add(BARCODE);
            table.Columns.Add(GOODSNAME);
            table.Columns.Add(STOCKAMOUNT);
            table.Columns.Add(CURRINVENTORYMOUNT);
            table.Columns.Add(SHORTAGEMOUNT);
            table.Columns.Add(SHORTAGEMONEY);
            table.Columns.Add(GOODSID);
            return table;
        }

        protected void btnSave_Click(object sender, EventArgs e)
        {
            try
            {
                SaveInventoryInfo();
                MessageBox.Show("您已保存当前盘点单！");
                btnEndInventory.Enabled = true;
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void SaveInventoryInfo()
        {
            InventoryInfos.WoCode = lblBillNo.Text.Trim();
            InventoryInfos.CreateUser = GenericContext.CurrUser;
            InventoryInfos.CreateDate = Convert.ToDateTime(lblCreateTime.Text.Trim());
            InventoryInfos.ReceivedDate = Convert.ToDateTime(txtDate.Text.Trim());
            InventoryInfos.Memo = txtMemo.Text.Trim();
            InventoryInfos.Contact = GenericContext.CurrUser.Contact;
            var coreAccess = new CoreDataAccess();
            coreAccess.BeginTransaction();
            try
            {
                coreAccess.SaveOrUpdate(InventoryInfos);
                var list = TransverToList(InventoryInfos.Id, InventoryInfos.State);
                foreach (GoodsInventoryItem item in list)
                {
                    coreAccess.SaveOrUpdate(item);
                }
                coreAccess.Commit();
            }
            catch (Exception)
            {
                coreAccess.RollBack();
                throw;
            }
            finally
            {
                coreAccess.Session.Close();
            }
            if (string.IsNullOrEmpty(WoCode))
                WoCode = lblBillNo.Text.Trim();
        }

        private IList<GoodsInventoryItem> TransverToList(Guid inventoryInfoId,string state)
        {
            var lists = new List<GoodsInventoryItem>();
            foreach (DataRow row in DataSource.Rows)
            {
                var inventoryItem = new GoodsInventoryItem();
                inventoryItem.CurrAmount = Convert.ToInt32(row[CURRINVENTORYMOUNT].ToString());
                inventoryItem.OrgAmount = Convert.ToInt32(row[STOCKAMOUNT]);
                inventoryItem.GoodsId= new Guid(row[GOODSID].ToString());
                inventoryItem.InventoryInfoId = inventoryInfoId;
                if(row[INVENTORYITEMID]!=null && !string.IsNullOrEmpty(row[INVENTORYITEMID].ToString()))
                    inventoryItem.Id = new Guid(row[INVENTORYITEMID].ToString());
                inventoryItem.State = state;
                lists.Add(inventoryItem);
            }
            return lists;
        }

        protected void txtBarcode_TextChanged(object sender, EventArgs e)
        {
            if(!string.IsNullOrEmpty(txtBarcode.Text.Trim()))
            {
                try
                {   
                    lblErrorInfo.Text = "";
                    var regex = new Regex(@"^([0-9]\d*)$");
                    if(!regex.Match(txtAmount.Text.Trim()).Success)
                    {
                        lblErrorInfo.Text = "数量必须为数字！";
                        return;
                    }
                    var coreAccess = new CoreDataAccess();
                    var exGoodInfo =
                        (ExGoodsInfo)
                        coreAccess.GetSingleObjectByProVal("ExGoodsInfo", "Goods.Code", txtBarcode.Text.Trim());
                    if (exGoodInfo != null)
                    {
                        lblBarcodeInfo.Text = exGoodInfo.Goods.Code;
                        lblNameInfo.Text = exGoodInfo.Goods.Name;
                        var rows = DataSource.Select(BARCODE+"='" + exGoodInfo.Goods.Code + "'");
                        if (rows.Length > 0)
                        {
                            if (!IsUpdateGoodsAmount)
                                rows[0][CURRINVENTORYMOUNT] = Convert.ToInt32(rows[0][CURRINVENTORYMOUNT]) +
                                                          Convert.ToInt32(txtAmount.Text.Trim());
                            else
                                rows[0][CURRINVENTORYMOUNT] = txtAmount.Text.Trim();
                            if (Convert.ToInt32(rows[0][STOCKAMOUNT]) > Convert.ToInt32(rows[0][CURRINVENTORYMOUNT]))
                                rows[0][SHORTAGEMOUNT] = Convert.ToInt32(rows[0][STOCKAMOUNT]) -
                                                         Convert.ToInt32(rows[0][CURRINVENTORYMOUNT]);
                            else
                                rows[0][SHORTAGEMOUNT] = 0;
                            rows[0][SHORTAGEMONEY] =string.Format("{0:C2}",Convert.ToInt32(rows[0][SHORTAGEMOUNT])*
                                                     exGoodInfo.Goods.BasePrice);
                        }
                        else
                        {
                            var row = DataSource.NewRow();
                            row[BARCODE] = exGoodInfo.Goods.Code;
                            row[GOODSNAME] = exGoodInfo.Goods.Name;
                            row[STOCKAMOUNT] = exGoodInfo.Amount;
                            row[CURRINVENTORYMOUNT] = txtAmount.Text.Trim();
                            row[GOODSID] = exGoodInfo.Goods.Id;
                            if (Convert.ToInt32(row[STOCKAMOUNT]) > Convert.ToInt32(row[CURRINVENTORYMOUNT]))
                                row[SHORTAGEMOUNT] = Convert.ToInt32(row[STOCKAMOUNT]) -
                                                     Convert.ToInt32(row[CURRINVENTORYMOUNT]);
                            else
                                row[SHORTAGEMOUNT] = 0;
                            row[SHORTAGEMONEY] = string.Format("{0:C2}",Convert.ToInt32(row[SHORTAGEMOUNT])*exGoodInfo.Goods.BasePrice);
                            DataSource.Rows.Add(row);
                        }
                    }
                    pgList.BindGrid();
                    txtBarcode.Text = "";
                    txtBarcode.Focus();
                    IsUpdateGoodsAmount = false;
                    SetInventoryAmountInfo();
                }
                catch (Exception exception)
                {
                    MessageBox.Show(exception.Message);
                }
            }
        }

        protected void btnInventory_Click(object sender, EventArgs e)
        {
            InventoryState = "盘点中";
            txtBarcode.Enabled = true;
            txtAmount.Enabled = true;
            btnAdd.Enabled = true;
        }

        protected void btnEndInventory_Click(object sender, EventArgs e)
        {
            InventoryState = "已完成";
            SaveInventoryInfo();
            btnSave.Enabled = false;
            btnInventory.Enabled = false;
            btnEndInventory.Enabled = false;
            MessageBox.Show("您已成功结束当前盘点！");
        }

        protected void btnDelete_Click(object sender, EventArgs e)
        {
            try
            {

                DeleteInventoryInfo();            
                MessageBox.Show("您已成功删除当前盘点单！");
                Response.Redirect("InventoryEdit.aspx", false);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void DeleteInventoryInfo()
        {
            if(!string.IsNullOrEmpty(WoCode))
            {
                var corAccess = new CoreDataAccess();
                corAccess.BeginTransaction();
                try
                {
                    var condition = new NameValueCollection();
                    condition.Add("InventoryInfoId", InventoryInfos.Id.ToString());
                    var list = corAccess.GetObjectList("GoodsInventoryItem", condition);
                    foreach (GoodsInventoryItem item in list)
                    {
                        corAccess.Delete(item);
                    }
                    corAccess.Delete(InventoryInfos);
                    corAccess.Commit();
                }
                catch (Exception exception)
                {
                    corAccess.Session.Transaction.Rollback();
                    throw exception;
                }
                finally
                {
                    corAccess.CloseSession();
                }
            }
        }

        private void SetInventoryAmountInfo()
        {
            if(DataSource.Rows.Count>0)
            {
                int currCount = 0;
                int moreCount = 0;
                int lessCount = 0;
                int notMCount = 0;
                int count = 0;
                double shortageMoney = 0.00;
                foreach (DataRow dataRow in DataSource.Rows)
                {
                    currCount = currCount +Convert.ToInt32(dataRow[CURRINVENTORYMOUNT]);
                    if (Convert.ToInt32(dataRow[CURRINVENTORYMOUNT]) > Convert.ToInt32(dataRow[STOCKAMOUNT]))
                        moreCount = moreCount + Convert.ToInt32(dataRow[CURRINVENTORYMOUNT]) -
                                    Convert.ToInt32(dataRow[STOCKAMOUNT]);
                    lessCount = Convert.ToInt32(dataRow[SHORTAGEMOUNT]) + lessCount;
                    notMCount = Convert.ToInt32(dataRow[SHORTAGEMOUNT]) + notMCount;
                    count = count + Convert.ToInt32(dataRow[STOCKAMOUNT]);
                    shortageMoney = shortageMoney + Convert.ToDouble(dataRow[SHORTAGEMONEY].ToString().Replace("￥", ""));
                }
                lblCorrespondCount.Text = currCount.ToString();
                lblMore.Text = moreCount.ToString();
                lblLess.Text = lessCount.ToString();
                lblNotManifestCount.Text = notMCount.ToString();
                lblCount.Text = count.ToString();
                lblTotalMoney.Text = string.Format("{0:C2}", shortageMoney);
            }
        }

        protected void pgList_OnGridItemSelect(object sender, VitCode.Web.UI.PaginationGridItemSelectArgs e)
        {
            var rows = DataSource.Select(BARCODE + "='" + e.SelectedDataKeyValue + "'");
            if(rows.Length>0)
            {
                txtBarcode.Text = rows[0][BARCODE].ToString();
                txtAmount.Text = rows[0][CURRINVENTORYMOUNT].ToString();
                lblBarcodeInfo.Text = rows[0][BARCODE].ToString();
                lblNameInfo.Text = rows[0][GOODSNAME].ToString();
                IsUpdateGoodsAmount = true;
            }
        }

        private bool IsUpdateGoodsAmount
        {
            get
            {
                if (ViewState["_isUpdateGoodsAmount"] == null)
                    return false;
                return (bool)ViewState["_isUpdateGoodsAmount"];
            }
            set { ViewState["_isUpdateGoodsAmount"] = value; }
        }
    }
}
